#include "precompiled.h"
#include "app_Grid.h"

using namespace app;

// TGridTable	/////////////////////////////////////////////////////////////////

//
TGridTable::TGridTable(
	TGridCtrl &GridCtrl_
) 
:GridCtrl(GridCtrl_)
,dataTable(NULL) 
,dataTableRecord(NULL)
{
}

//
void TGridTable::ConnectData(prs::TDataTable* DataTable) {
	dataTable = DataTable;
	dataTableRecord = NULL;
}

//
void TGridTable::ConnectData(prs::TDataTableRecord* DataTableRecord) {
	dataTable = NULL;
	dataTableRecord = DataTableRecord;
}

//
int TGridTable::GetNumberRows() { 
	if (dataTableRecord) {
		return 1;
	}
	return dataTable->Records.Array.Count(); 
}

//
int TGridTable::GetNumberCols() { 
	return GetDataTable()->Fields.Array.Count(); 
}

//
wxString TGridTable::GetColLabelValue( int col ) {
	prs::TDataField &Field = GetDataTable()->Fields.Array.Get(col);
	wxString S = Field.FieldId.GetValue().S();

	const char* NodeType = Field.GetNodeTypeEx();
	if ( NodeType == prs::TDataDict::nodeType_TDataFieldRefR ) {
		S << "*";
	}
	return S;
}

//
wxString TGridTable::GetRowLabelValue( int row ) {
	//prs::TDataTableRecord &Record = dataTable->Records.Array.Get(row);
	return wxString() << GetDataTableRecord(row)->RecordId.GetValue();
}

//
wxString TGridTable::GetValue(int row, int col) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	return wxString() << val->GetValueAsString();
}

//
long TGridTable::GetValueAsLong( int row, int col ) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	const char* nodeType = val->GetNodeTypeEx();

	if ( nodeType == prs::TDataDict::nodeType_TDataValueInteger ) {
		prs::TDataValueInteger *temp = static_cast<prs::TDataValueInteger*>( val );
		if ( !temp->GetNull() ) {
			return temp->GetValue();
		}
		return 0;
	}
	svl::TExcept("GetValueAsLong::nodeType != \"TDataValueInteger\"");
	return 0;
}

//
double TGridTable::GetValueAsDouble( int row, int col ) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	const char* nodeType = val->GetNodeTypeEx();

	if ( nodeType == prs::TDataDict::nodeType_TDataValueDouble ) {
		prs::TDataValueDouble *temp = static_cast<prs::TDataValueDouble*>( val );
		if ( !temp->GetNull() ) {
			return temp->GetValue();
		}
		return 0;
	}
	svl::TExcept("GetValueAsDouble::nodeType != \"TDataValueDouble\"");
	return 0;
}

//
void TGridTable::SetValue( int row, int col, const wxString &str ) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	const char* nodeType = val->GetNodeTypeEx();

	if ( nodeType == prs::TDataDict::nodeType_TDataValueString ) {
		prs::TDataValueString *temp = dynamic_cast<prs::TDataValueString*>( val );
		temp->SetValue( str.c_str() );
	}
}

//
void TGridTable::SetValueAsLong( int row, int col, long value ) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	const char* nodeType = val->GetNodeTypeEx();

	if ( nodeType == prs::TDataDict::nodeType_TDataValueInteger ) {
		prs::TDataValueInteger *temp = dynamic_cast<prs::TDataValueInteger*>( val );
		temp->SetValue( value );
	}
}

//
void TGridTable::SetValueAsDouble(int row, int col, double value) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	const char* nodeType = val->GetNodeTypeEx();

	if ( nodeType == prs::TDataDict::nodeType_TDataValueDouble ) {
		prs::TDataValueDouble *temp = dynamic_cast<prs::TDataValueDouble*>( val );
		temp->SetValue( value );

/*********?????
    wxGridCellEditor* Editor = GridCtrl.GetCellEditor(row,col);
		if (Editor->GetValue().Length() > 0)	{
			temp->SetValue( value );
		}
		else {
			temp->SetNull();
		}
***********/	
	}
}

//
wxString TGridTable::GetTypeName(int row, int col) {
	prs::TDataTableRecord *rec = GetDataTableRecord(row);
	prs::TDataValue *val = &rec->Values.Array.Get( col );
	const char* nodeType = val->GetNodeTypeEx();

	if ( nodeType == prs::TDataDict::nodeType_TDataValueInteger ) {
		return wxGRID_VALUE_NUMBER;
	}
	if ( nodeType == prs::TDataDict::nodeType_TDataValueDouble ) {
		return wxGRID_VALUE_FLOAT;
	}
	return wxGRID_VALUE_STRING;
}

//
bool TGridTable::CanGetValueAs( int WXUNUSED(row), int col, const wxString& typeName ) {
	prs::TDataField &DataField = GetDataTable()->Fields.Array.Get( col );
	const char* nodeType = DataField.GetNodeTypeEx();

	if ( typeName == wxGRID_VALUE_NUMBER ) {
		return nodeType == prs::TDataDict::nodeType_TDataFieldInteger;
	}
	if ( typeName == wxGRID_VALUE_FLOAT ) {
		return nodeType == prs::TDataDict::nodeType_TDataFieldDouble;
	}
	if ( typeName == wxGRID_VALUE_STRING ) {
		return true;
	}
	return false;
}

//
bool TGridTable::CanSetValueAs( int row, int col, const wxString& typeName ) {
  return CanGetValueAs(row, col, typeName);
}

//
bool TGridTable::IsEmptyCell( int row, int col ) { 
	//prs::TDataTableRecord *rec = GetDataTableRecord(row);
	//prs::TDataValue *val = &rec->Values.Array.Get( col );
  //return val->GetNull(); 
  return false;
}

// TGridCtrl //////////////////////////////////////////////////////////////////

//
TGridCtrl::TGridCtrl(wxWindow *parent
	,	prs::TDataTables &DataTables_
	, wxWindowID id
	, const wxPoint& pos
	, const wxSize& size
	, long style
	, const wxString& name
)
:wxGrid( parent, id, pos, size, style, name)
,DataTables(DataTables_)
,gridTable(*this)
{
}

//
TGridCtrl::~TGridCtrl() {
	HideCellEditControl();
	ClearSelection();
	SetTable( NULL );
	//Refresh();
}

//
void TGridCtrl::ConnectData(prs::TDataTable *DataTable) {
	BeginBatch();

	HideCellEditControl();
	ClearSelection();

	//!!!SetName(_table->TableId.GetValue().S());	

	gridTable.ConnectData( DataTable );
	SetTable( &gridTable );
	
	//Fit();
	EndBatch();
	//Refresh();
}

//
void TGridCtrl::ConnectData(prs::TDataTableRecord* DataTableRecord) {
	BeginBatch();

	HideCellEditControl();
	ClearSelection();

	gridTable.ConnectData( DataTableRecord );
	SetTable( &gridTable );
	
	EndBatch();
}

//
void TGridCtrl::DisconnectData() {
	BeginBatch();

	HideCellEditControl();
	ClearSelection();

	SetTable( NULL );

	EndBatch();
	//Refresh();
}
